import time
from queue import Queue
from xhs import common_db
from xhs import config
from datetime import datetime, timedelta
from xhs.ui_signal import ui_signal
from xhs.my_log import log
from typing import List, Dict

# 任务队列，供设备线程使用
task_queue = Queue()

# 统计加载任务的循环次数
loop_count = 0

# 记录已经入队的任务ID，避免重复入队
queued_task_ids = set()


def filter_exists_tasks(tasks: List[Dict], key: str = "red_id"):
    """
    从 tasks 中根据 red_id 在数据库中是否已存在，拆分出存在与不存在的两部分。

    :param tasks: 原始任务列表，每个元素是 dict，包含 red_id
    :param key: 要判断存在性的字段名，默认是 'red_id'
    :return: (not_exists_list, exists_list)
    """
    # 1. 提取所有 red_id
    id_list = [task[key] for task in tasks if key in task]

    if not id_list:
        return tasks, []

    # 2. 一次性查出哪些已存在
    existing_docs = common_db.db_send.find({key: {"$in": id_list}}, {key: 1})
    existing_ids = set(doc[key] for doc in existing_docs)

    # 3. 拆分成两个列表
    exists_list = []
    not_exists_list = []

    for task in tasks:
        value = task.get(key)
        if value in existing_ids:
            exists_list.append(task)
            common_db.db_source.update_one(
                {"_id": task["_id"]},
                {
                    "$set": {
                        config.system + "processed": True,
                        config.system + "processed_time": datetime.utcnow()
                    }
                }
            )
        else:
            not_exists_list.append(task)

    return not_exists_list, exists_list


# 查询数据，放到队列中
def load_tasks_loop():
    """
    循环从 MongoDB 加载未处理的任务到队列
    过滤 status == "new" 的任务，避免重复
    """
    while True:

        # 当前时间 - 10 分钟
        ten_minutes_ago = datetime.now() - timedelta(minutes=config.data_time_limit)

        # 格式化为字符串
        time_str = ten_minutes_ago.strftime("%Y-%m-%d %H:%M:%S")

        tasks = list(
            common_db.db_source.find({
                "comm_time": {"$gte": time_str},
                "$or": [
                    {config.system + "processed": False},
                    {config.system + "processed": {"$exists": False}}
                ]
            }).sort("comm_time", 1).limit(config.data_count_limit)
        )

        new_add_count = 0  # 本轮新增的任务计数

        for task in tasks:
            task_id = str(task.get("_id"))
            if task_id not in queued_task_ids:
                task_queue.put(task)
                queued_task_ids.add(task_id)
                new_add_count += 1

        # 调用过滤函数（过滤已存在的 red_id）
        # tasks, exists_list = filter_exists_tasks(tasks)
        log(f"查库间隔{config.data_interval}秒,{ten_minutes_ago}至今的数据,查询:{len(tasks)}条,去重后入队:{new_add_count},队列剩余:{task_queue.qsize()}")
        time.sleep(config.data_interval);


def data_device_load():
    """
    从 MongoDB 加载设备数据，按 device_id 排序
    :return: 设备列表（每个是 dict）
    """
    devices = list(common_db.db_device.find().sort("device_name", 1))
    return devices


def data_device_load_open():
    """
    从 MongoDB 加载 open_status 为“开启”的设备数据，按 device_id 升序排序
    :return: 设备列表（每个是 dict）
    """
    query = {"open_status": "开启"}

    devices = list(common_db.db_device.find(query))
    return devices


def data_device_add(device_info: dict):
    """
    添加设备到数据库，如果已存在则忽略。

    :param device_info: dict 包含 device_id、brand、model、version、device_name 等字段
    """
    # 检查是否已存在
    existing = common_db.db_device.find_one({"device_name": device_info["device_name"]})
    if existing:
        return

    # 补充默认字段
    device_info.setdefault("device_name", device_info["device_id"])  # 默认用 device_id 作名称
    device_info.setdefault("open_status", "关闭")  # 初始为关闭
    device_info.setdefault("app", "1")  # 默认使用app1
    device_info.setdefault("count", 0)  # 新增默认0

    common_db.db_device.insert_one(device_info)


def data_device_delete(device_id: str):
    """
    删除指定 device_id 的设备
    :param device_id: 设备 ID
    """
    result = common_db.db_device.delete_one({"device_id": device_id})
    if result.deleted_count == 0:
        print(f"[WARN] 未找到 device_id={device_id}，无法删除")


def data_device_set_status(device_id: str, status: str):
    """
    设置指定设备的状态为“开启”或“关闭”
    """
    if status not in ("开启", "关闭"):
        raise ValueError("status 参数必须是 '开启' 或 '关闭'")

    result = common_db.db_device.update_one(
        {"device_id": device_id},
        {"$set": {"open_status": status}}
    )
    if result.matched_count == 0:
        print(f"[WARN] 未找到 device_id={device_id} 的设备")

def data_device_set_note(device_id: str, note: str):
    result = common_db.db_device.update_one(
        {"device_id": device_id},
        {"$set": {"note": note}}
    )
    if result.matched_count == 0:
        print(f"[WARN] 未找到 device_id={device_id} 的设备")


def check_red_id_exists(red_id: str) -> bool:
    """
    判断指定 red_id 是否存在
    """
    result = common_db.db_send.find_one({"red_id": red_id})
    if result:
        return True
    else:
        return False


def data_device_set_app(device_id: str, app: str):
    """
    设置指定设备的状态为“开启”或“关闭”
    """
    if app not in ("1", "2"):
        raise ValueError("app 参数必须是 '1' 或 '2'")

    result = common_db.db_device.update_one(
        {"device_id": device_id},
        {"$set": {"app": app, "count": 0}}
    )
    if result.matched_count == 0:
        print(f"[WARN] 未找到 device_id={device_id} 的设备")
